package com.whale.cloud.util.rest.dataengine;

import com.whale.cloud.exception.CommonException;
import com.whale.cloud.util.StringUtils;
import com.whale.cloud.util.rest.condition.ELogic;
import com.whale.cloud.util.rest.condition.ERelation;
import com.whale.cloud.util.rest.schema.T_SYS_COLUMN;

import java.util.ArrayList;
import java.util.List;

/** Created by paco on 5/6/2017. 逻辑表达式 */
public class LogicExpression {
  private ELogic el; //逻辑符，如：and、or、[not ]exists
  private RelationExpression rExpression;
  private List<LogicExpression> allExpression = new ArrayList<LogicExpression>();

  public LogicExpression() {}

  public LogicExpression(String condition, ELogic el) {
    if (StringUtils.isNull(condition)) {
      throw new CommonException("-60", "条件不能为空");
    }
    int index = condition.indexOf(":");
    if (index < 0) {
      throw new CommonException("-60", "条件错误");
    }
    String columnCode = condition.substring(0, index);
    String value = condition.substring(index + 1);
    this.el = el;

    /*
    ERelation er=null;
    //判断是否是范围，格式：以空格（0个或多个）[或( 开始，以]或)空格（0个或多个）结尾
    //比如：[1 to 3) 或[1 to 3] 或 (1 to 3) 或 (1 to 3]
    Pattern pp = Pattern.compile("^\\s*[\\[\\{][\\s\\S]+[\\}\\]]\\s*$"); //(?<!\\\\)
    Matcher mm = pp.matcher(value);

    if(mm.find()){er=ERelation.range;}
    else{er=ERelation.getERelation("");}
    */

    rExpression = new RelationExpression(columnCode, value, ERelation.range);
  }

  /**
   * @param columnDBName 字段名
   * @param value 字段值
   * @param ecode 关系运算符
   */
  public LogicExpression(String columnDBName, String value, String ecode, ELogic el) {
    ERelation er = ERelation.getERelation(ecode);
    rExpression = new RelationExpression(columnDBName, value, er);
    this.el = el;
  }

  public LogicExpression(String columnDBName, String value, ERelation er, ELogic el) {
    rExpression = new RelationExpression(columnDBName, value, er);
    this.el = el;
  }

  public LogicExpression combine(LogicExpression le, ELogic el) {
    if (this.rExpression != null) {

      LogicExpression temple = new LogicExpression();
      temple.el = this.el;
      temple.rExpression =
          new RelationExpression(
              rExpression.columnDBName, rExpression.value, rExpression.comparison);
      this.rExpression = null;

      this.allExpression.add(temple);
      temple = this.combine(le, el);
      return temple;
    }

    /*
    if(this.allExpression.size()<=0){
        le.el=el;
        return le;
    }
    */

    le.el = el;
    allExpression.add(le);
    return this;
  }

  /*
  public LogicExpression combine(String columnDBName,String value,ERelation er,ELogic el){
      return this.combine(new LogicExpression(columnDBName,value,er,el),el);
  }

  public LogicExpression combine(String condition,ELogic el){
      return this.combine(new LogicExpression(condition,el),el);
  }
  */

  public String getDesc() {
    if (rExpression == null) {
      return "";
    }
    return rExpression.getDesc();
  }

  public T_SYS_COLUMN getColumn() {
    return rExpression.column;
  }

  public String getValue() {
    return rExpression.value;
  }

  public String getColumnDBName() {
    return rExpression.columnDBName;
  }

  public ERelation getERelation() {
    return rExpression.comparison;
  }

  public void setEl(ELogic el) {
    this.el = el;
  }

  public ELogic getEl() {
    return this.el;
  }

  /**
   * le不作为子表达式
   *
   * @param le
   */
  public void addLogicExpression(LogicExpression le, ELogic el) {
    if (le == null) {
      return;
    }

    if (le.allExpression.size() > 0) {
      le.allExpression.get(0).el = el;
      if (rExpression != null) {
        LogicExpression temple = new LogicExpression();
        temple.el = this.el;
        temple.rExpression =
            new RelationExpression(
                rExpression.columnDBName, rExpression.value, rExpression.comparison);
        this.rExpression = null;

        this.allExpression.add(temple);
      }
      allExpression.addAll(le.getAllExpression());
      return;
    }
    combine(le, el);
  }

  public List<LogicExpression> getAllExpression() {
    return this.allExpression;
  }

  /** */
  class RelationExpression {
    private ERelation
        comparison; //比较符，如：>、>=、<、<=、=、!=、[not ]like、[not ]in、[not ]regexp、between...and...

    private String columnDBName;
    private T_SYS_COLUMN column;
    private String value;
    private String desc;

    public RelationExpression(String columnDBName, String value, ERelation r) {
      if (StringUtils.isNull(columnDBName)) {
        throw new CommonException("-50", "字段不能为空");
      }

      this.columnDBName = columnDBName;
      if (StringUtils.isNotNull(value)) {
        value = value.replaceAll("§l§", "(* ");
        value = value.replaceAll("§r§", ")");
      }
      this.value = value;
      this.comparison = r;
      //this.desc=column.getShowName()+r.getDesc()+StringUtils.valueOf(value,"");
    }

    public String getDesc() {
      return this.desc;
    }
  }
}
